package net.Group.AccessService;

import java.io.FileInputStream;
import java.util.HashMap;

import javax.swing.JTextArea;

import myPackage.ChatOutput;
import myPackage.RBACUtil;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.endpoint.Message;
import net.jxta.endpoint.MessageElement;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.PipeMsgEvent;
import net.jxta.pipe.PipeMsgListener;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.PipeAdvertisement;

public class QueryIn extends Thread implements PipeMsgListener {
	
	private PeerGroup peerGroup = null;
	private QueryOut queryOut = null;
	private String myPeerID = null;
	private String myPeerName = null;
	private PipeService myPipeService =null;
	private PipeAdvertisement pipeAdv =null;
    private InputPipe pipeInput = null;	    
    public RBACUtil rbac = new RBACUtil();
    public HashMap authResultMap = new HashMap();
    
	 /** Creates a new instance of ChatInput */
    public QueryIn(PeerGroup group, QueryOut qout) 
    {
        this.peerGroup = group;
        this.queryOut = qout;
        getServices();        
    }
    
    private void getServices()
    {   //Obtaining Peer Group services
        System.out.println("[+]Getting Services for authorization pipe component...\n");
        myPipeService = peerGroup.getPipeService();
        myPeerID = peerGroup.getPeerID().toString();
        myPeerName = peerGroup.getPeerName();
        
        System.out.println("My Peer ID is " + myPeerID);
        
        try{ //Creates input pipe
            FileInputStream is = new FileInputStream("authPipe.adv");
            pipeAdv = (PipeAdvertisement)AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8,is);
            is.close();
        }catch(Exception e){
            //log.append("[+]Exception: " + e.getMessage()+"\n");
            e.printStackTrace();
            System.exit(-1);
        }
        //System.out.println("[+]Input Pipe Successfully Created.\n");
        
    }
    
    public void startListening() //This method will start listening for incoming messages thro created pipe
    {
        System.out.println("[+]Start Listening for Incoming Messages.\n");
        try{
            pipeInput = myPipeService.createInputPipe(pipeAdv,this);
            
        }catch(Exception e){
            System.out.println("[-]Exception: " + e.getMessage()+"\n");
            return;
        }
        if(pipeInput == null){
            System.out.println("[-]Failure in Opening Input Pipe :-(\n");
            System.exit(-1);
        }
    }
    
    public void stopListening() //This method will stop input pipe
    {
        pipeInput.close();
        System.out.println("[-]Input Pipe Closed for Incomming Message.\n");
    }
    //this listener will respond to incoming messages and show them in Designated area
    public void pipeMsgEvent(PipeMsgEvent ev)
    {
        System.out.println("[+]Query Message Received...\n");
        Message myMessage = null;
        try{
            myMessage = ev.getMessage();
            if(myMessage == null){
                return;
            }
        }catch(Exception e){
            System.out.println("[-]Exception happend when trying to get Message element!");
            e.printStackTrace();
        }
        //Assigning values to wanted Tages
        //ElementIterator el = myMessage.getMessageElements();
        String type = myMessage.getMessageElement("Type").toString();
        if (type.equals("Authorization")){
        	
        MessageElement me  = myMessage.getMessageElement("peerName");
        MessageElement me2 = myMessage.getMessageElement("peerID");
        MessageElement me3 = myMessage.getMessageElement("Operation");
        MessageElement me4 = myMessage.getMessageElement("Time");
        MessageElement me5 = myMessage.getMessageElement("ReceiverID");
        
        String peerName = me.toString();
        String peerID = me2.toString();
        String operation = me3.toString();
        String sentTime = me4.toString();
        String receiverID = me5.toString();
//        if(me5.toString() == null || !me5.equals(myPeerID)){
//            return;
//        }        	
        	if (receiverID.equals(myPeerID))
        	{
        			//get the role_name of peername and send it back
        			System.out.println("Authorization query received!");
        			wait(5);
        			System.out.println("Wait 5 second for LoT-RBAC system to update the role infomation");
        			//String role_name = rbac.getRoleName(peername);
        			boolean result = rbac.checkPermission(peerID,operation); 
      
        			if(result){
        				System.out.println("Permission Check Successful!\n");
        				this.stopListening();
        				queryOut.createAuthorizationResultMsg(peerID, operation,"PERMITTED");  
        				queryOut.b_authResult = true;
        				queryOut.startingPipe();
        				this.startListening();
        				
        			}
        			
        	}
        	
        }
        
        
       if (type.equals("AuthResult")){
    	   
       	String peerid = myMessage.getMessageElement("PeerID").toString();
    	String operation = myMessage.getMessageElement("Operation").toString();
    	String result = myMessage.getMessageElement("Result").toString();
    	String time = myMessage.getMessageElement("Time").toString();
    	if (peerid.equals(myPeerID))
    	{
    		String hashkey = peerid+operation;
    		authResultMap.put(hashkey, result);
    		
    		System.out.println(authResultMap.get(hashkey).toString());
    	}
    	
       }
        
    }
    
    public static void wait (int n){
        long t0,t1;
        t0=System.currentTimeMillis();
        do{
            t1=System.currentTimeMillis();
        }
        while (t1-t0<n*1000);
}
}
